#ifndef VENUS_SHADOW_MAPPING_SHADOW_MAPPING_DEMO_H
#define VENUS_SHADOW_MAPPING_SHADOW_MAPPING_DEMO_H

#include "common/venus.h"
#include "ui/glut_window.h"
#include "graphics/camera.h"
#include "graphics/fps_counter.h"

namespace venus {
struct Light {
  Light() : pos(2, 3, -2), at(0, 0, 0) { }
  Point pos;
  Point at;
};

class ShadowMappingDemo : public GlutWindow {
public:
  ShadowMappingDemo() 
      : GlutWindow("Shadow Mapping Demo",10, 10, 800, 600, 
                   GLUT_RGBA|GLUT_DOUBLE),
        camera_(Point(-2.5, 3.5, -2.5)), angle(0),
        fps_counter_(FpsCounter::kOverTime, 1) {
     render_program_ = NULL;
     fbo_ = NULL;
     shadow_map_ = NULL;
     camera_.set_velocity(0, 0, 0.5);
  }
  ~ShadowMappingDemo();
  bool Initialize();
  void OnIdle();
  void OnDisplay();
  void OnResize(int width, int height);
  void OnKeyboard(unsigned char key, int x, int y);
private:
  void UpdateTextureMatrix();
  void UpdateShadowMap();
  void RenderScene();
private:
  float angle;
  OrbitPerspectiveCameraGL camera_;
  ProgramGLSL *render_program_;
  FramebufferObject *fbo_;
  ImageTextureGL *shadow_map_;
  GLint shadow_map_var_;
  Light light_;
  float light_view_matrix_[16];
  float light_projection_matrix_[16];
  float camera_view_inverse_matrix_[16];
  int render_method_;
  int select_;
  FpsCounter fps_counter_;
  static const int shadow_map_width_ = 1024;
  static const int shadow_map_height_ = 1024;
};
} // namespace venus 

#endif // VENUS_SHADOW_MAPPING_SHADOW_MAPPING_DEMO_H